package com.nowcoder.community;

import com.nowcoder.community.dao.DiscussPostMapper;
import com.nowcoder.community.dao.elasticsearch.DiscussPostRepository;
import com.nowcoder.community.entity.DiscussPost;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class testElasticSearch {

    @Autowired
    private DiscussPostMapper discussPostMapper;


    @Autowired
    private DiscussPostRepository discussPostRepository;

//    @Autowired
//    private ElasticsearchTemplate elasticTemplate;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;



    @Test
    public void testInsert(){
        //每次插入一条数据
        discussPostRepository.save(discussPostMapper.selectDiscussPostById(241));
        discussPostRepository.save(discussPostMapper.selectDiscussPostById(242));
        discussPostRepository.save(discussPostMapper.selectDiscussPostById(243));
    }

    @Test
    public void testInsertList(){
        //一次插入多条数据
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(101,0,100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(102,0,100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(103,0,100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(111,0,100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(112,0,100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(131, 0, 100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(132, 0, 100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(133, 0, 100,0));
        discussPostRepository.saveAll(discussPostMapper.selectDiscussPost(134, 0, 100,0));
    }

    @Test
    public void testUpdate(){
        DiscussPost discussPost = discussPostMapper.selectDiscussPostById(231);
        discussPost.setContent("灌水！！！");
        discussPostRepository.save(discussPost);
    }

    @Test
    public void testDelete(){
        discussPostRepository.deleteAll();
    }


    //搜索结果 排序，分页，高亮
    //排序：type：置顶  score：分数  createtime
    //status：加精
    @Test
    public void testSearchByRepository(){
        //构建搜索条件
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
                .withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSorts(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSorts(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(PageRequest.of(0, 10))
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")

                ).build();

        SearchHits<DiscussPost> search = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);
        SearchPage<DiscussPost> page = SearchHitSupport.searchPageFor(search, searchQuery.getPageable());
        System.out.println(page.getTotalElements());
        System.out.println(page.getTotalPages());
        System.out.println(page.getNumber());
        System.out.println(page.getSize());
        for (SearchHit<DiscussPost> post : page) {
            //System.out.println(post.getHighlightFields()); //高亮内容
            System.out.println(post.getContent()); //原始内容
        }

    }


    //高亮
    @Test
    public void testSearch(){
        //构建搜索条件
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content"))
                .withSorts(SortBuilders.fieldSort("type").order(SortOrder.DESC))
                .withSorts(SortBuilders.fieldSort("score").order(SortOrder.DESC))
                .withSorts(SortBuilders.fieldSort("createTime").order(SortOrder.DESC))
                .withPageable(PageRequest.of(0, 10))
                .withHighlightFields(
                        new HighlightBuilder.Field("title").preTags("<em>").postTags("</em>"),
                        new HighlightBuilder.Field("content").preTags("<em>").postTags("</em>")

                ).build();
        //查询，获取查询结果
        SearchHits<DiscussPost> search = elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);
        //分页
        SearchPage<DiscussPost> page = SearchHitSupport.searchPageFor(search, searchQuery.getPageable());


        //高亮部分封装成一个page对象
        List<DiscussPost> list = new ArrayList<>();
        //遍历命中的数据
        for (SearchHit<DiscussPost> discussPostSearchHits:page){
            DiscussPost discussPost = discussPostSearchHits.getContent();
            if(discussPostSearchHits.getHighlightFields().get("title")!=null){
                discussPost.setTitle(discussPostSearchHits.getHighlightFields().get("title").get(0));
            }
            if (discussPostSearchHits.getHighlightFields().get("content")!=null){
                discussPost.setContent(discussPostSearchHits.getHighlightFields().get("content").get(0));
            }
            //System.out.println(discussPostSearchHits.getContent());
            list.add(discussPost);
        }

        PageImpl<DiscussPost> pageInfo = new PageImpl<>(list, searchQuery.getPageable(), search.getTotalHits());

        System.out.println(pageInfo.getTotalElements());
        System.out.println(pageInfo.getTotalPages());
        System.out.println(pageInfo.getNumber());
        System.out.println(pageInfo.getSize());
        for (DiscussPost discussPost : pageInfo) {
            System.out.println(discussPost);
        }

    }

}
